package com.woniu.order.service.impl;

import cn.hutool.core.util.IdUtil;
import com.alibaba.fastjson2.JSON;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.woniu.common.dto.*;
import com.woniu.common.entity.Addr;
import com.woniu.common.entity.ZyProduct;
import com.woniu.common.utils.JWTUtil;
import com.woniu.common.utils.PageParam;
import com.woniu.common.utils.ResponseData;
import com.woniu.common.dto.CouponStatusDTO;
import com.woniu.common.utils.ResponseEnum;
import com.woniu.order.dto.*;
import com.woniu.order.dto.OrderDetailDTO;
import com.woniu.order.feign.EcssOrderFeign;
import com.woniu.order.feign.ProductFeign;
import com.woniu.order.feign.UserFeign;
import com.woniu.order.mapper.OrderDetailMapper;
import com.woniu.order.pojo.Logistics;
import com.woniu.order.pojo.OrderDetail;
import com.woniu.order.pojo.ZyOrder;
import com.woniu.order.service.OrderDetailService;
import com.woniu.order.service.ZyOrderService;
import com.woniu.order.mapper.ZyOrderMapper;
import lombok.SneakyThrows;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;

import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import java.math.BigDecimal;
import java.util.*;
import java.util.stream.Collectors;

/**
* @author ltyipx
* @description 针对表【zy_order】的数据库操作Service实现
* @createDate 2024-08-07 09:44:03
*/
@Service
public class ZyOrderServiceImpl extends ServiceImpl<ZyOrderMapper, ZyOrder>
    implements ZyOrderService{
    @Autowired
    private ProductFeign productFeign;
    @Autowired
    private UserFeign userFeign;
    @Autowired
    private EcssOrderFeign ecssOrderFeign;

    @Autowired
    private ZyOrderMapper zyOrderMapper;
    @Autowired
    private OrderDetailService orderDetailService;
    @Autowired
    private OrderDetailMapper orderDetailMapper;
    @Autowired
    private HttpServletRequest request;
    @Autowired
    private LogisticsServiceImpl logisticsService;
    @PostMapping("/queryAllOrder")
    public ResponseData<?> queryAllOrder(@RequestBody PageParam<OrderDto> param){
        PageHelper.startPage(param.getPageNum(), param.getPageSize());
        List<ZyOrder> zyOrders = zyOrderMapper.queryAllOrder(param.getParam());
        PageInfo objectPageInfo = new PageInfo<>(zyOrders);
        return new ResponseData<>().success(objectPageInfo);
    }

    @Override
    public ResponseData<?> selectAllOrder(PageParam<OrderInquiryDto> params) {
        PageHelper.startPage(params.getPageNum(),params.getPageSize());
        List<OrderBreakDto> orderBreakDtos = zyOrderMapper.selectAllOrder(params.getParam());

        PageInfo objectPageInfo = new PageInfo<>(orderBreakDtos);
        return new ResponseData().success(objectPageInfo);
    }

    @Override
    public void addOrder(String userId, String orderId, List<ForOrderProductDTO> products) {
        ZyOrder order = new ZyOrder();
        //1、创建订单
        order.setId(orderId);
        order.setUserId(userId);

        List<String> collect = products.stream().map(e -> e.getId()).collect(Collectors.toList());
        String[] ids = collect.stream().toArray(String[]::new);
        ResponseData<List<ForOrderProductDTO>> responseData = productFeign.queryGoodsByIds(ids);
        List<ForOrderProductDTO> dataList = responseData.getData();
        BigDecimal totalPrice = new BigDecimal("0");
        for (ForOrderProductDTO data : dataList) {
            for (ForOrderProductDTO product : products) {
                if(data.getId().equals(product.getId())){
                    data.setBuyNum(product.getBuyNum());
                }
            }
            totalPrice = totalPrice.add(data.getPrice().multiply(new BigDecimal(data.getBuyNum())));
        }
        order.setTotalPrice(totalPrice);
        ResponseData<UserDTO> responseData1 = userFeign.queryUserById(userId);
        UserDTO user = responseData1.getData();
        order.setUserName(user.getUserName());
        order.setUserTel(user.getUserPhone());
        ResponseData<CustomDTO> responseData2 = userFeign.queryCustomByUserId(userId);
        CustomDTO customDTO = responseData2.getData();
        order.setCustomId(customDTO.getId());
        order.setCreateTime(new Date());
        order.setState(0);
        save(order);

        //2、创建订单详情
        for (ForOrderProductDTO product : dataList) {
            OrderDetail orderDetail = new OrderDetail();
            long id = IdUtil.getSnowflake().nextId();
            orderDetail.setId(String.valueOf(id));
            orderDetail.setOrderId(orderId);
            ResponseData<ProductTypeDTO> productTypeDTOResponseData = productFeign.queryProductTypeById(product.getProductType());
            ProductTypeDTO data = productTypeDTOResponseData.getData();
            String orderTypeId = data.getOrderTypeId();
            orderDetail.setOrderTypeId(orderTypeId);
            orderDetail.setOrderBusinessTypeId(product.getBusinessId());
            orderDetail.setUserId(userId);
            orderDetail.setProductId(product.getId());
            orderDetail.setProductName(product.getName());
            orderDetail.setProductPrice(product.getPrice());
            orderDetail.setProductType(product.getProductType());
            orderDetail.setBuyNum(product.getBuyNum());
            orderDetail.setCreateTime(new Date());
            orderDetail.setState(1);
            orderDetailService.save(orderDetail);

        //3.修改购物车
            if(products.size()>1){
                ResponseData res = productFeign.updateCart(userId,products);
            }

        }
    }

    @Override
    public void handleOrderStatus(String userId, String orderId) {
        ZyOrder order = getById(orderId);
        if(order.getState().equals(0)){
            //修改订单状态，回滚商品库存
            order.setState(5);
            updateById(order);
            orderDetailService.lambdaUpdate()
                    .setSql("state = 5")
                    .eq(OrderDetail::getOrderId,orderId)
                    .update();

            //回滚商品库存
            List<OrderDetail> list = orderDetailService.lambdaQuery().eq(OrderDetail::getOrderId, orderId).list();
            productFeign.rollBackStock(list);
        }
    }

    @Override
    public ResponseData<?> selOrderDetail(String orderId) {
        OrderDetailDTO orderDetailDTO = new OrderDetailDTO();
        ZyOrder order = lambdaQuery().eq(ZyOrder::getId, orderId).one();
        List<OrderDetail> orderDetails = orderDetailMapper.selOrderDetail(orderId);
//        BeanUtil.copyProperties(order,OrderDetailDTO.class);
        List<ZyProduct> zyProducts = productFeign.selectProduct(orderDetails.get(0).getProductId());
        Addr addr = userFeign.selectAddr(orderDetails.get(0).getAddressId());
        orderDetailDTO.setOrder(order);
        orderDetailDTO.setOrderDetails(orderDetails);
        orderDetailDTO.setProducts(zyProducts);
        orderDetailDTO.setAddress(addr);
        return new ResponseData<>().success(orderDetailDTO);
    }

    @Override
    @Transactional
    public ResponseData<?> payOrder(PayOrderDTO payOrderDTO) {
        String orderId = payOrderDTO.getOrderId();
        ZyOrder order = getById(orderId);
        //0.0判断用户是否已经支付过了
        if(order.getState().equals(2)){
            return new ResponseData<>().fail(ResponseEnum.DUPLICATE_PAY);
        }
        //1、修改订单状态；
        //1.1修改订单状态
        //1.1.5判断订单是否超时
        if (order.getState().equals(5)) {
            return new ResponseData<>().fail(ResponseEnum.ORDER_HAS_CANSEL);
        }

        order.setState(2);
        if(!payOrderDTO.getCouponId().equals("")){
            CouponStatusDTO couponStatusDTO = productFeign.queryCouponById(payOrderDTO.getCouponId()).getData();
            order.setDiscountAmount(couponStatusDTO.getCouponValue());
            order.setActualAmount(order.getTotalPrice().subtract(couponStatusDTO.getCouponValue()));
        }else {
            order.setDiscountAmount(new BigDecimal(0));
            order.setActualAmount(order.getTotalPrice());
        }
        order.setPaymentId(1);
        updateById(order);
        //1.2修改订单详情状态
        List<OrderDetail> orderDetailList = orderDetailService.lambdaQuery().eq(OrderDetail::getOrderId, orderId).list();
        for (OrderDetail orderDetail : orderDetailList) {

            if(orderDetail.getOrderTypeId().equals("2") || orderDetail.getOrderTypeId().equals("5")){
                //添加物流类订单详情信息
                orderDetail.setAddressId(payOrderDTO.getAddressId());
                ResponseData<AddrDTO> responseData = userFeign.queryAddrById(payOrderDTO.getAddressId());
                AddrDTO addrDTO = responseData.getData();
                String addressName = addrDTO.getProvince()+" "+addrDTO.getCity()+" "+addrDTO.getCounty()+" "+addrDTO.getDetail();
                orderDetail.setAddressName(addressName);
                orderDetail.setState(2);
            }else if(orderDetail.getOrderTypeId().equals("3")){
                //添加施工类订单详情信息

            }else if(orderDetail.getOrderTypeId().equals("4")){
                //添加签约类订单详情信息

            }
            orderDetailService.updateById(orderDetail);
        }
        // 2、修改优惠券状态；
        if(!payOrderDTO.getCouponId().equals("")){
            productFeign.UseCoupon(payOrderDTO.getCouponId());
        }
        //2.1扣余额，添加总消费金额
        ResponseData<UserDTO> userDTOResponseData = userFeign.queryUserById(order.getUserId());
        UserDTO userData = userDTOResponseData.getData();
        UserDTO userDTO = new UserDTO();
        userDTO.setId(order.getUserId());
        BigDecimal bigDecimal = new BigDecimal(userData.getUserPurse());
        BigDecimal subtract = bigDecimal.subtract(order.getActualAmount());
        userDTO.setUserPurse(subtract.toString());
        userDTO.setUserConsumeAmount(userData.getUserConsumeAmount().add(order.getActualAmount()));
        ResponseData<?> responseData = userFeign.UpdateUser(userDTO);

        //2.2修改商品已售量
        ArrayList<ForOrderProductDTO> forOrderProductDTOS = new ArrayList<>();
        for (OrderDetail orderDetail : orderDetailList) {
            ForOrderProductDTO forOrderProductDTO = new ForOrderProductDTO();
            forOrderProductDTO.setId(orderDetail.getProductId());
            forOrderProductDTO.setBuyNum(orderDetail.getBuyNum());
            forOrderProductDTOS.add(forOrderProductDTO);
        }
        ResponseData res = productFeign.updateProductSales(forOrderProductDTOS);



        // 3、判断该商品是否是ecss，如果是，则把订单信息传给ecss
        List<String> collect = orderDetailList
                .stream()
                .map(OrderDetail::getProductId)
                .collect(Collectors.toList());
        String[] productIds = collect.stream().toArray(String[]::new);
        List<ForOrderProductDTO> data = productFeign.queryGoodsByIds(productIds).getData();
        boolean flag = false;
        ArrayList<String> ecssProductIds = new ArrayList<>();
        for (ForOrderProductDTO product : data) {
            if(product.getEcss().equals(0)){
                flag = true;
                ecssProductIds.add(product.getId());
            }
        }
        if(flag){
            Map<String, Object> map = new HashMap<>();
            map.put("order",JSON.toJSONString(order));
            List<OrderDetail> orderDetailList1 = orderDetailList
                    .stream()
                    .filter(e -> ecssProductIds.contains(e.getProductId()))
                    .collect(Collectors.toList());
            map.put("orderDetailList",JSON.toJSONString(orderDetailList1));
            ecssOrderFeign.addOrderFromZy(JSON.toJSONString(map));
        }


        return new ResponseData<>().success();
    }

    @Override
    public ResponseData<?> queryPayCustomNumber() {
        Integer number = zyOrderMapper.queryPayCustomNumber();
        return new ResponseData<>().success(number);
    }

    @Override
    public ResponseData<?> payMoneyNumber() {
        Integer number = zyOrderMapper.payMoneyNumber();
        return new ResponseData<>().success(number);
    }

    @Override
    public ResponseData<?> isGoingToPay() {
        Integer number = zyOrderMapper.isGoingToPay();
        return new ResponseData<>().success(number);
    }

    @Override
    public ResponseData<?> isGoingToFahuo() {
        Integer number = zyOrderMapper.isGoingToFahuo();
        return new ResponseData<>().success(number);
    }



    @SneakyThrows
    @Override
    public ResponseData<?> queryOrderByExample(Integer state) {
        //参数:userId,state
        Cookie[] cookies = request.getCookies();
        String jwt = null;
        for (Cookie cookie : cookies) {
            if("jwt".equals(cookie.getName())){
                jwt = cookie.getValue();
            }
        }
        Map<String, Object> userInfo = JWTUtil.getUserInfo(jwt);
        String userId = userInfo.get("id").toString();
        List<OrderDto> orderList = zyOrderMapper.queryOrderByExample(userId,state);
        for (OrderDto orderDto : orderList) {
            ResponseData<ArrayList<payOrderDetailDTO>> responseData = (ResponseData<ArrayList<payOrderDetailDTO>>) orderDetailService.queryOrderDetailByOrderId(orderDto.getId());
            ArrayList<payOrderDetailDTO> list = responseData.getData();
            orderDto.setProductList(list);
        }

        return new ResponseData<>().success(orderList);
    }

    @Override
    public ResponseData<?> queryAllDateForEcharts() {
        ReturnDataForEcharts returnDataForEcharts = new ReturnDataForEcharts();
        //查询数据一，订单总数detail
        List<Integer> list = orderDetailMapper.orderDetailList();
        returnDataForEcharts.setDadaForEcharts1(list);
        //查询数据二，支付人数
        List<Integer> list1 = zyOrderMapper.orderPayNumberList();
        returnDataForEcharts.setDadaForEcharts2(list1);
        //查询金额
        List<Integer> list2 = zyOrderMapper.payList();
        returnDataForEcharts.setDadaForEcharts3(list2);
        //查询会话人数
        List<Integer> list3= userFeign.QueryHuihuaList();
        returnDataForEcharts.setDadaForEcharts4(list3);
        return new ResponseData<>().success(returnDataForEcharts);
    }

    @Override
    public ResponseData<?> queryLogisticsByOrderDetailId(String orderDetailId) {
        OrderDetail orderDetail = orderDetailService.getById(orderDetailId);
        Logistics logistics = logisticsService.getById(orderDetail.getLogisticsId());
        return new ResponseData<>().success(logistics);
    }

    @Override
    public ResponseData<?> confirmOrder(String orderDetailId) {
        OrderDetail orderDetail = orderDetailService.getById(orderDetailId);
        orderDetail.setState(4);
        orderDetailService.updateById(orderDetail);
        String orderId = orderDetail.getOrderId();
        lambdaUpdate().set(ZyOrder::getState,4)
                .eq(ZyOrder::getId,orderId)
                .update();

        //推送
        boolean b = ecssOrderFeign.shouhuoFromZy(orderDetail.getOrderId(), orderDetailId);
        return new ResponseData<>().success();
    }
}




